package me.ramswaroop.jbot.core.slack; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import me.ramswaroop.jbot.core.slack.models.RTM; import me.ramswaroop.jbot.core.slack.models.User; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.http.ResponseEntity; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.stereotype.Repository; import org.springframework.web.client.RestClientException; import org.springframework.web.client.RestTemplate; import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * @author ramswaroop * @version 14/08/2016 */ @Repository public class SlackDao { private static final Logger logger = LoggerFactory.getLogger(SlackDao.class); /** * Endpoint for RTM.start() */ @Value("${rtmUrl}") private String rtmUrl; /** * RTM object constructed from <a href="https://api.slack.com/methods/rtm.start">RTM.start()</a>. */ private RTM rtm; /** * Rest template to make http calls. */ private RestTemplate restTemplate; public RTM startRTM(String slackToken) { try { restTemplate = new RestTemplate(); rtm = new RTM(); // Custom Deserializers List<HttpMessageConverter<?>> httpMessageConverters = new ArrayList<>(); MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter(); Jackson2ObjectMapperBuilder mapperBuilder = new Jackson2ObjectMapperBuilder(); mapperBuilder.deserializerByType(RTM.class, new JsonDeserializer<RTM>() { @Override public RTM deserialize(JsonParser p, DeserializationContext ctxt) { try { final ObjectMapper objectMapper = new ObjectMapper(); JsonNode node = p.readValueAsTree(); RTM rtm = new RTM(); rtm.setWebSocketUrl(node.get("url").asText()); rtm.setUser(objectMapper.treeToValue(node.get("self"), User.class)); List<String> dmChannels = new ArrayList<>(); Iterator<JsonNode> iterator = node.get("ims").iterator(); while (iterator.hasNext()) { dmChannels.add(iterator.next().get("id").asText()); } rtm.setDmChannels(dmChannels); List<User> users = new ArrayList<>(); Iterator<JsonNode> userIterator = node.get("users").iterator(); while (userIterator.hasNext()) { users.add(objectMapper.treeToValue(userIterator.next(), User.class)); } rtm.setUsers(users); return rtm; } catch (Exception e) { logger.error("Error de-serializing RTM.start(): ", e); return null; } } }); jsonConverter.setObjectMapper(mapperBuilder.build()); httpMessageConverters.add(jsonConverter); restTemplate.setMessageConverters(httpMessageConverters); ResponseEntity<RTM> response = restTemplate.getForEntity(rtmUrl, RTM.class, slackToken); if (response.getBody() != null) { rtm.setWebSocketUrl(response.getBody().getWebSocketUrl()); rtm.setDmChannels(response.getBody().getDmChannels()); rtm.setUser(response.getBody().getUser()); rtm.setUsers(response.getBody().getUsers()); logger.debug("RTM connection successful. WebSocket URL: {}", rtm.getWebSocketUrl()); } else { logger.debug("RTM response invalid. Response: {}", response); } } catch (RestClientException e) { logger.error("RTM connection error. Exception: {}", e.getMessage()); } return rtm; } }